#!/usr/bin/env ruby
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

$header = %{
/**
* Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved.
*/

// Autogenerated file -- DO NOT EDIT!

#ifndef CROSS_VALUES_CROSS_VALUES_H
#define CROSS_VALUES_CROSS_VALUES_H

}

Dir.glob("#{ARGV[1]}/*values_gen.h").each do |values_h|
    $header += "#include \"generated_values/#{File.basename(values_h)}\"\n"
end
$header += "\n"
$header += "#include <cstddef>\n"
$header += "#include \"libpandabase/utils/arch.h\"\n"
$header += "#include \"runtime/entrypoints/entrypoints.h\"\n\n"

def generate(input_file, output_file)
    data = File.read(input_file)
    names = data.scan /DEFINE_VALUE\((\w+),/
    File.open(output_file, "w") do |file|
        file.puts $header
        file.puts "namespace panda::cross_values {"

        names.sort_by(&:first).each do |define|
            file.puts %<
[[maybe_unused]] static constexpr ptrdiff_t Get#{define[0].split('_').collect(&:capitalize).join}(Arch arch)
{
    switch (arch) {
>
            Dir.glob("#{ARGV[1]}/*_values_gen.h").each do |values_h|
                file.puts "        case Arch::#{File.basename(values_h, "_values_gen.h")}:\n"
                file.puts "            return cross_values::#{File.basename(values_h, "_values_gen.h")}::#{define[0]}_VAL;\n"
            end
            file.puts "        default:\n"
            file.puts "            LOG(FATAL, COMMON) << \"No cross-values generated for \" << GetStringFromArch(arch);\n"
            file.puts "            UNREACHABLE();\n"
            file.puts "    }\n"
            file.puts "}\n"
        end

        file.puts %<
// Specific getter for TLS entrypoints offsets:
[[maybe_unused]] static constexpr ptrdiff_t GetManagedThreadEntrypointOffset(Arch arch, panda::EntrypointId id)
{
    return GetManagedThreadEntrypointsOffset(arch) + static_cast<size_t>(id) * PointerSize(arch);
}

>
        file.puts "}  // namespace panda::cross_values"
        file.puts
        file.puts "#endif  // CROSS_VALUES_CROSS_VALUES_H"
        file.puts
    end
end

abort "Failed: input file, generated values directory and output file required!" if ARGV.size < 3

generate ARGV[0], ARGV[2]
